package cn.founder.user.service.impl;


import cn.founder.basic.constant.BaseConstant;
import cn.founder.basic.exception.BusinessException;
import cn.founder.basic.service.impl.BaseServiceImpl;
import cn.founder.basic.util.MD5Utils;
import cn.founder.basic.util.StrUtils;
import cn.founder.user.domain.Logininfo;
import cn.founder.user.domain.User;
import cn.founder.user.dto.UserDto;
import cn.founder.user.mapper.LogininfoMapper;
import cn.founder.user.mapper.UserMapper;
import cn.founder.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {
    //基础crud继承

    @Autowired
    private UserMapper userMapper;

    //注入进行redis数据库操作
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    //注入logininfomapper
    private LogininfoMapper logininfoMapper;


    //有其他业务新增需自己重写
    //前端用户注册  传递值
    @Transactional
    @Override
    public void phoneRegister(UserDto userDto) {
        //前端数据传递过来4个字段判断是否为空
        String password = userDto.getPassword();
        String phone = userDto.getPhone();
        String confirmPwd = userDto.getConfirmPwd();
        String verifycode = userDto.getVerifycode();
        if(StringUtils.isEmpty(password)
                || StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(confirmPwd)
                || StringUtils.isEmpty(verifycode)){
            throw new BusinessException("请填写正确的信息，谢谢");
        }
        //判断验证码是否为空  是否正确
        Object codeobj = redisTemplate.opsForValue()
                //通过 注册的头+手机号作为key查询 验证码是否过期
                .get(BaseConstant.BUSINESS_TYPE_REGISTER + userDto.getPhone());
        if(codeobj == null){
            throw new BusinessException("验证码已过期请重新获取");
        }
        //判断输入的验证码是否正确
        String code = codeobj.toString().split(":")[0];
            //不区分大小写 比对
        if(!code.equalsIgnoreCase(verifycode)){
            throw new BusinessException("验证码错误，请重新输入");
        }
        //两次密码是否一致
        if(!password.equals(confirmPwd)){
            throw new BusinessException("两次密码不一致，请重新填写！");
        }
        //如果信息不为空或空字符串，验证码未过期，密码正确  查询用户是否注册过
        if(userMapper.loadByPhone(phone) != null ){
            //如果不为空  用户注册过  直接提示报错
            throw new BusinessException("该手机已注册，请直接登录！");
        }
        //上面如果都没出现  就保存用户信息(注册)
        //-首先保存logininfo数据  创建一个方法
            //把userDto的数据传递给User
        User user = userDto2User(userDto);
            //把user的数据给 logininfo对象
        Logininfo info = user2loininfo(user);
        //开始保存登录logininfo数据
        info.setType(1);//设置type为1   必定是前端用户
        logininfoMapper.save(info);
        //将返回的自增id重新设置
        user.setLogininfo_id(info.getId());
        //保存user数据
        userMapper.save(user);



    }

    private Logininfo user2loininfo(User user) {
        //声明一个对象
        Logininfo info = new Logininfo();
        //把user的参数 复制给info
        BeanUtils.copyProperties(user,info);
        //返回info
        return info;
    }


    //这是上面的方法
    private User userDto2User(UserDto userDto) {
        //声明一个返回对象
        User user = new User();
        //设置用户名和手机号
        user.setUsername(userDto.getPhone());
        user.setPhone(userDto.getPhone());
        //获取一个新的盐值
        String salt = StrUtils.getComplexRandomString(32);
        //将注册传递的密码和盐值一起加密获得密码
        String psdbyMd5 = MD5Utils.encrypByMd5(userDto.getPassword() + salt);
        //设置盐值和密码
        user.setSalt(salt);
        //设置密码
        user.setPassword(psdbyMd5);
        //设置完成后返回对象
        return user;
    }


}
